#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "log.hpp"
#include "protocol.hpp"
#include "inetaddr.hpp"

/*用于测式的客户端代码，根据业务层自定义*/
#define CONV(addr) (struct sockaddr *)(addr)

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        LOG(FATAL) << "Usage:./client ip port";
        return 1;
    }
    uint16_t port = std::stoi(argv[2]);
    std::string ip = argv[1];
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        LOG(FATAL) << "socket create fail";
        return 2;
    }
    LOG(DEBUG) << "socket create successful fd:" << sockfd;
    struct sockaddr_in s;
    s.sin_family = AF_INET;
    s.sin_port = htons(port);
    s.sin_addr.s_addr = inet_addr(ip.c_str());
    inetaddr server;
    server.setaddr(s);
    ::connect(sockfd, CONV(server.sockaddr()), server.len());

    while (true)
    {
        int x, y;
        char oper;
        std::string send_message;
        std::cout << "X=:";
        std::cin >> x;
        std::cout << "Y=:";
        std::cin >> y;
        std::cout << "oper=:";
        std::cin >> oper;

        request client_rq(x, y, oper);
        // 1.序列化请求+编码
        client_rq.Serialize(send_message);
        encode(send_message);

        ::send(sockfd, send_message.c_str(), send_message.size(), 0);
        // 接收服务器数据
        char recv_buf[1024];


        int n = ::recv(sockfd, recv_buf, sizeof(recv_buf) - 1, 0);
        recv_buf[n]=0;
        std::cout<<recv_buf<<std::endl;
        //2.解包并反序列化服务器应答
        std::string recv_message=recv_buf;


        std::string respond_str;
        decode(recv_message,&respond_str);
        respond client_rp;
        client_rp.DeSerialize(respond_str);

        if(client_rp.CODE()==DIV_ZERO_ERROR){
            std::cout<<"被除数不能为0";
        }
        else if(client_rp.CODE()==OPER_ERROR){
            std::cout<<"不支持当前符号操作";
        }
        else if(client_rp.CODE()==0){
            client_rp.display();
        }
    }
    return 0;
}
